home *** CD-ROM | disk | FTP | other *** search
- {
- > Bruce Schneier suggests keyboard latency as a good source of randomness.
- > I suspect you'd find the delays far more regular than you'd guess, but
- > it's worth looking at. Show us an implementation!
-
- Thanks, DJ. (And I was hoping a simple appeal to a recognized authority
- would suffice! I guess I should have known better.) But fair enough -
- here's an admittedly crude implementation:
- }
-
- program TestKey;
-
- { Test keyboard latency as a potential source of random numbers. }
- { NOTE - NO ERROR CHECKING! }
-
- uses
- Dos, Crt;
-
- const
- FileName = 'RANDOM.TST';
-
- var
- PrevTime : Word;
- RandByte : Byte;
- Regs : Registers;
- Bit : Word;
- RandFile : file of Byte;
- Ch : Char;
-
- begin
- { open the file }
- Assign( RandFile, FileName );
- Rewrite( RandFile );
-
- { get DOS time and save low word }
- Regs.AH := 0;
- Intr( $1A, Regs );
- PrevTime := Regs.DX;
-
- Bit := 0;
- RandByte := 0;
- WriteLn( 'Start typing now. Press <ESC> to quit.' );
-
- repeat
- { get a keystroke }
- repeat until KeyPressed;
- Ch := ReadKey;
-
- { if the Escape key }
- if Ch = #27 then
- Break;
-
- { get DOS time }
- Regs.AH := 0;
- Intr( $1A, Regs );
-
- { calculate the time difference, isolate the low-order bit, and }
- { use it to build the hopefully-random byte in progress. }
- RandByte := RandByte + ( ( Lo( Regs.DX - PrevTime ) and 1 ) shl Bit );
- PrevTime := Regs.DX;
- Inc( Bit );
-
- { If we have a full byte, write it to the file and start over }
- if ( Bit > 7 ) then begin
- Write( RandFile, RandByte );
- RandByte := 0
- Bit := 0;
- end;
-
- { Ignore special keys, display the rest }
- if Ch = #0 then
- Ch := ReadKey
- else
- Write( Ch );
- if Ch = #13 then
- Write( #10 )
-
- until False;
- Close( RandFile )
- end.
-
- {
- I ran this thing and typed in the first page of a DOC file. This is what I
- got:
-
- 24 98 AD 94 E2 C8 00 58 20 83 09 F1 5D F5 76 59
- 31 A9 86 DC 32 6D 96 17 65 C4 75 31 A3 18 F5 97
- 87 0A 69 B4 B6 E7 0A C1 F8 09 BE B0 7B C5 4A BA
- 69 42 8C D4 E4 71 12 DF 5E 19 5C A0 0D 79 D7 F1
- 66 BC 40 36 E9 8D DB B5 37 A9 7A 0C 02 90 05 04
- EA 53 38 CA 94 18 92 8A 46 A6 F1 56 D0 E7 38 97
- 25 2D C3 C8 7E 79 DE 02 58 FC 36 7E BC 3C F9 6D
- E6 2E C0 28 06 AD C1 4B 55 CD C4 98 DD 08 DD 4E
- 11 56 76 83 BC 7A AF 05 F6 AC C3 40 28 D5 2B 8E
- C1 93 B5 F9 54 E2 00 3D 5A 5D 37 36 C3 5F 37 3A
- AB 60 36 72 27 26 21 86 2F B4 6B D9 70 94 DE 00
- C8 23 34 5F 83 C9 FB AF F8 F5 CE 21 B3 40 FA ED
- 21 4B 65 00 D9 A0 6E 43 E4 FF 66 1B BC 17 80 29
- FD 6F 10 4B D7 D3 ED 5C C9 18 0E 24 89 1F 03 BC
- B3 0B CB E5 1E 16 B8 DA 99 EC 93 84 7E 8A FE 61
- 9D B7 2E 30 11 7F 0A C6 83 C2 C1 97 3B 08 61 8D
- 7B 5E 7E 69 99 F8 F3 36 BA 31 6E 41 60 8C DC B7
- 48 FB 44 A2 78 D5 AF 88 D9 10 50 E7 C7 BE 68 41
- C2 E8 D8 1B
-
- The distribution of bytes looks like this:
-
- 0 1 2 3 4 5 6 7 8 9 A B C D E F
- +-----------------------------------------------------------------
- 0 | 4 0 2 1 1 2 1 0 2 2 3 1 1 1 1 0
- 1 | 2 2 1 0 0 0 1 2 3 1 0 2 0 0 1 1
- 2 | 1 3 0 1 2 1 1 1 2 1 0 1 0 1 2 1
- 3 | 1 3 1 0 1 0 5 3 2 0 1 1 1 1 0 0
- 4 | 3 2 1 1 1 0 1 0 1 0 1 3 0 0 1 0
- 5 | 1 0 0 1 1 1 2 0 2 1 1 0 2 2 2 2
- 6 | 2 2 0 0 0 2 2 0 1 3 0 1 0 2 2 1
- 7 | 1 1 1 0 0 1 2 0 1 2 2 2 0 0 4 1
- 8 | 1 0 0 4 1 0 2 1 1 1 2 0 2 2 1 0
- 9 | 1 0 1 2 3 0 1 3 2 2 0 0 0 1 0 0
- A | 2 0 1 1 0 0 1 0 0 2 0 1 1 2 0 3
- B | 1 0 0 2 2 2 1 2 1 0 2 0 5 0 2 0
- C | 1 4 2 3 2 1 1 1 3 2 1 1 0 1 1 0
- D | 1 0 0 1 1 2 0 2 1 3 1 1 2 2 2 1
- E | 0 0 2 0 2 1 1 3 1 1 1 0 1 2 0 0
- F | 0 3 0 1 0 3 1 0 3 2 1 2 1 1 1 1
-
-
- Question - is it random? Well, it's far too small a sample to be sure, and I
- wasn't about to retype "War and Peace" to get a bigger sample. It passes
- one test of randomness - non-compressability. LHA won't compress it, anyway.
- (A text file of similar size compressed to 64%.) I don't consider this
- definite proof of randomness, although it looks hopeful.
-
- Question - is it unpredictable? Given the above source code and the list of
- bytes generated, I don't think I could predict what the next byte would be.
-
- Question - can it be reliably reproduced? Not at my level of typing ability,
- unless I cheat and just hold down a key. Even then, there are minor
- variations between bytes.
-
- Problem - the timer is too coarse. It uses the BIOS time-of-day count, which
- ticks over about 18.2 times per second. For a 30-wpm (3 character-per-second)
- typist like me, it _seems_ to produce acceptable results. For a professional
- typist, churning out 110 wpm (11 characters per second), it probably won't.
- Something using the 8253 timer (a modification of the Abrash "Zen Timer", for
- example) would probably be adequate for even the fastest typist, but that's a
- bit too exotic for me to attempt.
-
- Problem - it takes a lot of typing to generate a decent pad. By my
- calculations, a 110-wpm typist would have to type for 20 minutes to create a
- pad big enough to encrypt one double-spaced typewritten page. Possible
- solution - rewrite the thing as a TSR, so that a typist can do useful work
- while generating random (?) numbers in the background. Then, turn the whole
- typing pool loose on the problem.
-
- Does anyone have a better timer routine and a faster typist?
- }